package bll

import (
	"context"
	"fmt"
	"manager/utils"

	"manager/event"
	"manager/model"
	"manager/model/entity"
	"manager/store"
	"manager/store/postgres"
	"time"

	"manager/auth"
)

type order struct {
	iOrder store.IOrder
}

var Order = &order{
	iOrder: postgres.Order,
}

func (a *order) init() func() {
	return func() {}
}

func (a *order) onEvent(*event.Data) {}

// Create 创建
func (a *order) Create(ctx context.Context, in *model.OrderCreateRequest) error {
	var (
		err error
	)

	// 门店校验
	if _, err = postgres.Store.Find(ctx, in.StoreId); err != nil {
		return fmt.Errorf("shop not found")
	}

	// 车辆校验
	if info, _err := postgres.Ebike.Find(ctx, in.EbikeId); _err != nil {
		return fmt.Errorf("车辆不存在")
	} else if info.SaleTime > 0 {
		return fmt.Errorf("车辆已售出")
	}

	// 获取用户Id
	if in.UserId == 0 {
		in.UserId, _ = auth.ContextUserID(ctx)
	}

	// 生成订单号
	in.OrderNo = utils.Generate(time.Now())

	// 构建创建现场数据
	c := buildOrder(in)
	_, err = a.iOrder.Create(ctx, c)
	if err != nil {
		return err
	}

	// 更新售出时间和门店信息
	if err = postgres.GetDB(ctx).Model(&entity.Ebike{}).Where("id = ?", in.EbikeId).Updates(map[string]interface{}{
		"store_id":  in.StoreId,
		"sale_time": time.Now().Unix(),
	}).Error; err != nil {
		return err
	}
	return nil
}

// Update 更新
func (a *order) Update(ctx context.Context, in *model.OrderUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)

	updateAt := time.Now().Unix()
	in.UpdatedAt = &updateAt

	if in.EbikeTypeId != nil {
		dict["ebike_type_id"] = in.EbikeTypeId
	}

	if in.EbikeId != nil {
		dict["ebike_id"] = in.EbikeId
	}

	if in.UserId != nil {
		dict["user_id"] = in.UserId
	}

	if in.Price != nil {
		dict["price"] = in.Price
	}

	if in.OrderNo != nil {
		dict["order_no"] = in.OrderNo
	}

	if in.StoreId != nil {
		dict["store_id"] = in.StoreId
	}

	if in.StoreName != nil {
		dict["store_name"] = in.StoreName
	}

	if in.AreaId != nil {
		dict["area_id"] = in.AreaId
	}

	if in.AreaName != nil {
		dict["area_name"] = in.AreaName
	}

	if in.Status != nil {
		dict["status"] = in.Status
	}

	if in.UpdatedAt != nil {
		dict["updated_at"] = in.UpdatedAt
	}

	// do other update here

	return a.iOrder.Update(ctx, in.Id, dict)
}

// Delete 删除
func (a *order) Delete(ctx context.Context, in *model.OrderDeleteRequest) error {
	return a.iOrder.Delete(ctx, in.Id)
}

// List 列表查询
func (a *order) List(ctx context.Context, in *model.OrderListRequest) (*model.OrderListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.Order
		out   = &model.OrderListResponse{}
	)

	if total, list, err = a.iOrder.List(ctx, in); err != nil {
		return nil, err
	}

	out.Total = total
	out.List = model.OrdersEntityToDto(list)

	return out, nil
}

// Find 列表查询
func (a *order) Find(ctx context.Context, in *model.OrderInfoRequest) (*model.OrderInfo, error) {
	var (
		err  error
		data *entity.Order
		out  = &model.OrderInfo{}
	)

	if data, err = a.iOrder.Find(ctx, in); err != nil {
		return nil, err
	}

	out = model.OrderEntityToDto(data)
	return out, nil
}

// buildOrder 构建创建数据现场
func buildOrder(in *model.OrderCreateRequest) *entity.Order {
	// todo: check the entity is required
	return &entity.Order{

		EbikeTypeId: in.EbikeTypeId,

		EbikeId: in.EbikeId,

		UserId: in.UserId,

		Price: in.Price,

		OrderNo: in.OrderNo,

		StoreId: in.StoreId,

		StoreName: in.StoreName,

		AreaId: in.AreaId,

		AreaName: in.AreaName,

		Status: in.Status,

		CreatedAt: time.Now().Unix(),

		UpdatedAt: time.Now().Unix(),
	}
}
